package com.ajocer.springbootinit.manager;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.ajocer.springbootinit.common.ErrorCode;
import com.ajocer.springbootinit.config.CosClientConfig;
import com.ajocer.springbootinit.exception.BusinessException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

/**
 * Cos 对象存储操作
 * */
@Component
@Slf4j
public class CosManager {

    @Resource
    private CosClientConfig cosClientConfig;

    @Resource
    private COSClient cosClient;
    
    private static final String DEFAULT_AVATAR_KEY = "user_avatar/default/avatar.png";

    @PostConstruct
    public void init() {
        log.info("COS配置初始化: bucket={}, region={}, host={}", 
                cosClientConfig.getBucket(), 
                cosClientConfig.getRegion(), 
                cosClientConfig.getCosHost());
        
        // 确保默认头像存在
        try {
            ensureDefaultAvatarExists();
        } catch (Exception e) {
            log.error("初始化默认头像失败", e);
        }
    }

    /**
     * 上传对象
     *
     * @param key 唯一键
     * @param localFilePath 本地文件路径
     * @return 可访问的URL
     */
    public String putObject(String key, String localFilePath) {
        log.info("开始上传文件: key={}, localPath={}", key, localFilePath);
        File file = new File(localFilePath);
        if (!file.exists()) {
            log.error("文件不存在: {}", localFilePath);
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件不存在");
        }
        return putObject(key, file);
    }

    /**
     * 上传对象
     *
     * @param key 唯一键
     * @param file 文件
     * @return 可访问的URL
     */
    public String putObject(String key, File file) {
        if (file == null || !file.exists()) {
            log.error("上传的文件为空或不存在");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传的文件为空或不存在");
        }
        
        log.info("上传文件到COS: key={}, fileSize={}", key, file.length());
        
        try {
            // 设置元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.length());
            
            // 执行上传
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    cosClientConfig.getBucket(), 
                    key, 
                    file
            );
            putObjectRequest.setMetadata(metadata);
            
            PutObjectResult result = cosClient.putObject(putObjectRequest);
            log.info("文件上传成功: key={}, etag={}", key, result.getETag());
            
            // 返回可访问URL
            String url = getObjectUrl(key, cosClientConfig.getCosHost());
            log.info("文件访问URL: {}", url);
            return url;
        } catch (CosServiceException e) {
            log.error("COS服务端错误: errorCode={}, statusCode={}, requestId={}", 
                    e.getErrorCode(), e.getStatusCode(), e.getRequestId(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "对象存储服务错误: " + e.getErrorMessage());
        } catch (CosClientException e) {
            log.error("COS客户端错误: ", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "对象存储客户端错误: " + e.getMessage());
        } catch (Exception e) {
            log.error("文件上传失败: key={}", key, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 上传对象
     *
     * @param key 唯一键
     * @param inputStream 输入流
     * @return 可访问的URL
     */
    public String putObject(String key, InputStream inputStream) {
        if (inputStream == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "输入流为空");
        }
        
        log.info("从输入流上传文件到COS: key={}", key);
        File tempFile = null;
        
        try {
            tempFile = File.createTempFile("cos_upload_", ".tmp");
            FileUtils.copyInputStreamToFile(inputStream, tempFile);
            return putObject(key, tempFile);
        } catch (IOException e) {
            log.error("处理输入流失败: ", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件处理失败: " + e.getMessage());
        } finally {
            if (tempFile != null && tempFile.exists()) {
                boolean deleted = tempFile.delete();
                if (!deleted) {
                    log.warn("临时文件删除失败: {}", tempFile.getAbsolutePath());
                }
            }
        }
    }
    
    /**
     * 检查默认头像是否存在，如果不存在则上传
     */
    public void ensureDefaultAvatarExists() {
        log.info("检查默认头像是否存在: {}", DEFAULT_AVATAR_KEY);
        
        try {
            // 检查默认头像是否存在
            try {
                cosClient.getObjectMetadata(cosClientConfig.getBucket(), DEFAULT_AVATAR_KEY);
                log.info("默认头像已存在");
                return;
            } catch (CosServiceException e) {
                // 如果是404错误，说明文件不存在，需要上传
                if (e.getStatusCode() != 404) {
                    log.error("检查默认头像时发生错误: ", e);
                    return;
                }
                log.info("默认头像不存在，准备创建并上传");
            }
            
            // 创建一个简单的默认头像（1x1蓝色像素）
            // 这是一个有效的最小PNG图像
            byte[] defaultAvatarBytes = {
                (byte)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 
                0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 
                0x02, 0x00, 0x00, 0x00, 0x25, 0x0B, (byte)0xE6, (byte)0x89, 0x00, 0x00, 0x00, 
                0x01, 0x73, 0x52, 0x47, 0x42, 0x00, (byte)0xAE, (byte)0xCE, 0x1C, (byte)0xE9, 
                0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 
                0x00, 0x0B, 0x13, 0x01, 0x00, (byte)0x9A, (byte)0x9C, 0x18, 0x00, 0x00, 0x00, 
                0x30, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, (byte)0xED, (byte)0xD2, 0x31, 0x01, 
                0x00, 0x00, 0x0C, (byte)0xC3, 0x30, 0x00, (byte)0xBF, (byte)0xA7, 0x7D, 0x09, 
                (byte)0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0x4C, 0x00, 0x01, (byte)0x82, 0x11, 
                (byte)0xC3, (byte)0xD5, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, (byte)0xAE, 
                0x42, 0x60, (byte)0x82
            };
            
            try (InputStream inputStream = new java.io.ByteArrayInputStream(defaultAvatarBytes)) {
                String url = putObject(DEFAULT_AVATAR_KEY, inputStream);
                log.info("默认头像创建并上传成功: {}", url);
            } catch (Exception e) {
                log.error("创建默认头像失败: ", e);
            }
        } catch (Exception e) {
            log.error("确保默认头像存在时发生错误: ", e);
        }
    }
    
    /**
     * 获取对象访问URL
     *
     * @param key 唯一键
     * @param cosHost 访问域名
     * @return 对象访问URL
     */
    private String getObjectUrl(String key, String cosHost) {
        String url;
        // 检查cosHost是否已经包含协议前缀
        if (cosHost.startsWith("http://") || cosHost.startsWith("https://")) {
            url = String.format("%s/%s", cosHost, key);
        } else {
        // 对象访问URL格式为：域名/key
            url = String.format("https://%s/%s", cosHost, key);
        }
        log.debug("生成对象访问URL: {}", url);
        return url;
    }
}
